/*
 * @Author: wangshiyang
 * @Date: 2023-02-07 16:15:14
 * @LastEditors: sxj xtt_sxj3@163.com
 * @LastEditTime: 2025-04-21 12:45:18
 * @Description: 请填写简介
 */
import { defineConfig, loadEnv } from 'vite'
import { fileURLToPath, URL } from 'node:url'
import vue from '@vitejs/plugin-vue'
import { viteExternalsPlugin } from 'vite-plugin-externals'
import { insertHtml, h } from 'vite-plugin-insert-html'
import { viteStaticCopy } from 'vite-plugin-static-copy'
import compress from 'vite-plugin-compression'
// import vueDevTools from 'vite-plugin-vue-devtools'

const config = (context) => {
  const mode = context.mode //当前构建模式(development/production)
  const envDir = 'env' // 环境变量文件的文件夹，相对于项目的路径，也可以用 nodejs 函数拼接绝对路径
  const isProd = mode === 'production' // 是否生产环境
  //使用 Vite 提供的 loadEnv 函数从指定目录（在这里是 "env" 文件夹）加载环境变量文件中的变量。
  const env = loadEnv(mode, envDir) // 加载环境变量
  console.log(env)
  const cesiumBaseUrl = env['VITE_CESIUM_BASE_URL'] // 从环境变量获取的 Cesium 基础 URL
  console.log(cesiumBaseUrl)
  // 默认 base 是 '/'
  const base = '/' //应用的基础路径
  //插件配置
  const plugins = [
    vue(),
    // vueDevTools(),
    /* viteExternalsPlugin优势：
      减小打包体积：Cesium 是一个非常大的库，外部化它可以显著减小最终打包文件的大小
      利用 CDN：生产环境中可以从 CDN 加载 Cesium，提高加载速度
      缓存优化：用户浏览器可以单独缓存 Cesium 库
      并行加载：应用代码和 Cesium 库可以并行加载
    */
    viteExternalsPlugin(
      {
        /* 指定要外部化的依赖及其全局变量名
        这告诉 Vite 不要将 Cesium 库打包到最终的 JavaScript 包中,而是期望它作为全局变量 window.Cesium 在运行时可用 */
        cesium: 'Cesium', // 外部化 cesium 依赖，之后全局访问形式是 window['Cesium']
      },
      {
        disableInServe: true, //开发环境不启用外部化
      },
    ),
    insertHtml({
      head: [
        // 生产模式使用 CDN 或已部署的 CesiumJS 在线库链接，开发模式用拷贝的库文件，根据 VITE_CESIUM_BASE_URL 自动拼接
        h('script', {
          // 因为涉及前端路径访问，所以开发模式最好显式拼接 base 路径，适配不同 base 路径的情况
          src: isProd ? `${cesiumBaseUrl}Cesium.js` : `${base}${cesiumBaseUrl}Cesium.js`,
        }),
        h('link', {
          rel: 'stylesheet',
          href: isProd
            ? `${cesiumBaseUrl}Widgets/widgets.css`
            : `${base}${cesiumBaseUrl}Widgets/widgets.css`,
        }),
      ],
    }),
  ]

  if (!isProd) {
    // 开发模式，复制 node_modules 下的 cesium 依赖
    const cesiumLibraryRoot = 'node_modules/cesium/Build/CesiumUnminified/'
    const cesiumLibraryCopyToRootPath = 'libs/cesium/' // 相对于打包后的路径
    const cesiumStaticSourceCopyOptions = ['Assets', 'ThirdParty', 'Workers', 'Widgets'].map(
      (dirName) => {
        return {
          src: `${cesiumLibraryRoot}${dirName}/*`, // 注意后面的 * 字符，文件夹全量复制
          dest: `${cesiumLibraryCopyToRootPath}${dirName}`,
        }
      },
    )
    plugins.push(
      //viteStaticCopy 插件会在构建过程中自动创建目标目录（libs/cesium）,在开发模式下，Vite 会将这些复制的文件放在内存中并正确处理请求，而不是真正地写入磁盘
      viteStaticCopy({
        targets: [
          // 主库文件，开发时选用非压缩版的 IIFE 格式主库文件
          {
            src: `${cesiumLibraryRoot}Cesium.js`,
            dest: cesiumLibraryCopyToRootPath,
          },
          // 四大静态文件夹
          ...cesiumStaticSourceCopyOptions,
        ],
      }),
    )
  }

  plugins.push(
    compress({
      threshold: 10 * 1024, // 10KB 以下不压缩
    }),
  )

  const resolve = {
    alias: {
      // 配置路径别名，将 '@' 符号映射到项目的 src 目录
      // 使用 fileURLToPath 和 URL 将相对路径转换为绝对路径
      // 这样在项目中可以使用 '@/components/xxx' 的方式导入文件，而不需要使用 '../../components/xxx' 这样的相对路径
      // import.meta.url 表示当前模块的 URL，用于获取当前文件的路径
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  }

  const css = {
    // css预处理器
    //preprocessorOptions: 定义预处理器的选项
    preprocessorOptions: {
      //scss: 针对 SCSS 预处理器的特定配置
      scss: {
        // additionalData: 在每个 SCSS 文件的开头自动添加指定的代码
        // 引入 mixin.scss 这样就可以在全局中使用 mixin.scss中预定义的变量了
        additionalData: '@import "@/assets/style/mixin.scss";',
      },
    },
  }

  return {
    base,
    envDir,
    mode,
    plugins,
    resolve,
    css,
  }
}

// https://vitejs.dev/config/
export default defineConfig(config)
